#ifndef __mmu_h__
#define __mmu_h__

#include "tlb.h"
#include "cp15.h"
#include "cachectrl.h"
class CMMU
{
	bool enabled;//arm v7:All TLBs are disabled at reset.

	CTLB itlb,dtlb;
	CCacheCtrl cache;
public:
	CMMU () {}
	bool is_enabled() 
	{

		return cp15.ControlRegister().M;
	}
	bool is_cache_enabled() {return 0;}//cp15.ControlRegister().C;}


	bool fix_tlb(__u32 va,TLB_ENTRY *p_tlb_entry);
	__u32 translate_va(__u32 va,TLB_ENTRY* p_tlb_entry);
	bool permission_check(TLB_ENTRY* p_tlb_entry,bool write,bool code);

	bool translate_and_check(__u32 va,__u32 *p_mva,bool write,bool code);

	bool read_byte (__u32 address,__u8 *p_dat );
	bool read_short(__u32 address,__u16 *p_dat );
	bool read_int(__u32 address,__u32 *p_dat );
	bool read_insn(__u32 address,__u32 *p_dat );

	bool write_byte (__u32 address,__u8  dat);
	bool write_short(__u32 address,__u16 dat);
	bool write_int(__u32 address,__u32 dat);

	CCP15 cp15;
	void exec_mcr(__u32 cmd,__u32 Rd);
	__u32 exec_mrc(__u32 cmd);
};



/*
Table B4-1 First-level descriptor format (VMSAv6, subpages enabled)
Fault             IGN                                                0 0
Coarse page table Coarse page table base address  IMP Domain SBZ     0 1
Section           Section base address SBZ TEX AP IMP Domain SBZ C B 1 0
                  RESERVED                                           1 1
*/
typedef struct mmu_level1_fault
{
	__u32 c_0:2;// shuld  be 00
	__u32 ign:30;
} LEVEL1_FAULT;

typedef struct mmu_level1_coarse
{
	__u32 c_0:2;// shuld  be 01
	__u32 sbz:3;
	__u32 domain:4;
	__u32 imp:1;
	__u32 base:22;
} LEVEL1_COARSE;

typedef struct mmu_level1_section
{
	__u32 c_0:2;// shuld  be 10
	__u32 b:1;
	__u32 c:1;
	__u32 sbz1:1;
	__u32 domain:4;
	__u32 imp:1;
	__u32 ap:2;
	__u32 tex:3;
	__u32 sbz2:5;
	__u32 base:12;
} LEVEL1_SECTION;

typedef struct mmu_level1_rserved
{
	__u32 c_0:2;// shuld  be 11
	__u32 reserved:30;
} LEVEL1_RVSD;
/*
Table B4-2 First-level descriptor format (VMSAv6, subpages disabled)

Fault        IGN                                                                                            0 0
Coarse page  table Coarse page table base address       IMP  Domain SBZ                                      0 1
Section      Section base address SBZ 0 nG S APX TEX AP IMP Domai                                     XN C B 1 0
Supersection Supersection base address Baseaddress[35:32]SBZ 1 nGS APX TEX AP IMP Base address[39:36] XN C B 1 0
             RESERVED                                                                                        1 1
*/

typedef struct mmu_level1_fault_no_subpg
{
	__u32 c_0:2;// shuld  be 00
	__u32 ign:30;
} LEVEL2_FAULT_NO_SUBPG;
//
typedef struct mmu_level1_coarse_subpg
{
	__u32 c_0:2;// shuld  be 01
	__u32 sbz:3;
	__u32 domain:4;
	__u32 imp:1;
	__u32 base:22;
} LEVEL1_COARSE_NO_SUBPG;

typedef struct mmu_level1_section_subpg
{
	__u32 c_0:2;// shuld  be 10
	__u32 b:1;
	__u32 c:1;
	__u32 xn:1;
	__u32 domain:4;
	__u32 imp:1;
	__u32 ap:2;
	__u32 tex:3;
	__u32 apx:1;
	__u32 s:1;
	__u32 ng:1;
	__u32 super:1;
	__u32 base:12;
} LEVEL1_SECTION_NO_SUBPG;


typedef struct mmu_level1_supersection_subpg
{
	__u32 c_0:2;// shuld  be 10
	__u32 b:1;
	__u32 c:1;
	__u32 xn:1;
	__u32 basehi:4;
	__u32 imp:1;
	__u32 ap:2;
	__u32 tex:3;
	__u32 apx:1;
	__u32 s:1;
	__u32 ng:1;
	__u32 super:1;
	__u32 basemi:4;
	__u32 baselo:8;
} LEVEL1_SUPERSECTION_NO_SUBPG;

typedef struct mmu_level1_rserved_subpg
{
	__u32 c_0:2;// shuld  be 11
	__u32 reserved:30;
} LEVEL1_RVSD_SUBPG;

/*
Table B4-3 Second-level descriptor format (subpages enabled)
Fault IGN                                                           0 0
Large page Large page base address      SBZ TEX AP3 AP2 AP1 AP0 C B 0 1
Small page Small page base address              AP3 AP2 AP1 AP0 C B 1 0
Extended small page Extended small page base address SBZ TEX AP C B 1 1
*/
typedef struct level2_fault
{
	__u32 c_0:2;// shuld  be 00
	__u32 ign:30;
} LEVEL2_FAULT;

typedef struct level2_page_large
{
	__u32 c_0:2;// shuld  be 01
	__u32 b:1;
	__u32 c:1;
	__u32 ap0:2;
	__u32 ap1:2;
	__u32 ap2:2;
	__u32 ap3:2;
	__u32 tex:3;
	__u32 sbz:1;
	__u32 base:16;
} LEVEL2_PAGE_LARGE;

typedef struct level2_page_small
{
	__u32 c_0:2;// shuld  be 01
	__u32 b:1;
	__u32 c:1;
	__u32 ap0:2;
	__u32 ap1:2;
	__u32 ap2:2;
	__u32 ap3:2;
	__u32 base:20;
} LEVEL2_PAGE_SMALL;

typedef struct level2_page_small_ext
{
	__u32 c_0:2;// shuld  be 10
	__u32 b:1;
	__u32 c:1;
	__u32 ap:2;
	__u32 tex:3;
	__u32 sbz:3;
	__u32 base:20;
} LEVEL2_PAGE_SMALL_EXT;

/*
Table B4-4 Second-level descriptor format (subpages disabled)
Fault      IGN                                                           0 0
Large page Large page base address            XN TEX nG S APX SBZ AP C B 0 1
Extended small page Extended small page base address nG S APX TEX AP C B 1 XN
*/



typedef struct level2_page_large_no_subpg
{
	__u32 c_0:2;// shuld  be 01
	__u32 b:1;
	__u32 c:1;
	__u32 ap:2;
	__u32 sbz1:3;
	__u32 apx:1;
	__u32 s:1;
	__u32 ng:1;
	__u32 tex:3;
	__u32 sbz2:1;
	__u32 base:16;
} LEVEL2_PAGE_LARGE_NO_SUBPG;


typedef struct level2_page_small_ext_no_subpg
{
	__u32 xn:1;
	__u32 c_1:1;// shuld  be 10
	__u32 b:1;
	__u32 c:1;
	__u32 ap:2;
	__u32 tex:3;
	__u32 apx:1;
	__u32 s:1;
	__u32 ng:1;
	__u32 base:20;
} LEVEL2_PAGE_SMALL_EXT_NO_SUBPG;


#endif //__mmu_h__